//Половину ошибок без контекста не исправишь, под линуксом не скомпилируешь, на сколько можно "продвинуться" в переписывании кода не понятно. Не понравилось:(

/**
* @brief
*		Find errors and decrease probability of getting errors of the same kind in the future
*		This piece of code won't compile and it doesn't describe an entire algorithm: just part of some page storage
*
* @author
*		AnnaM
*/

#include <Windows.h>
#include <stdio.h>


//Зачем начинается все с единицы? Это вносит путаницу!
enum PAGE_COLOR
{
	PG_COLOR_GREEN = 0, /* page may be released without high overhead */
	PG_COLOR_YELLOW, /* nice to have */
	PG_COLOR_RED	/* page is actively used */
};


/**
 * UINT Key of a page in hash-table (prepared from color and address)
 */
union PageKey
{
	struct
	{
        CHAR	cColor: 8;
		UINT	cAddr: 24;
	};

	UINT	uKey;
};


/* Prepare from 2 chars the key of the same configuration as in PageKey */
#define CALC_PAGE_KEY( Addr, Color )	(  (Color) + (Addr) << 8 ) 


/**
 * Descriptor of a single guest physical page
 */
struct PageDesc
{
	PageKey			uKey;	

	/* list support */
	PageDesc		*next, *prev;
};

//тут стоит заменить точки на ->

#define PAGE_INIT( Desc, Addr, Color )              \
    {                                               \
        (Desc)->uKey = CALC_PAGE_KEY( Addr, Color ); \
        (Desc)->next = (Desc)->prev = NULL;           \
    }
        

/* storage for pages of all colors */
static PageDesc* PageStrg[ 3 ];

void PageStrgInit()
{
	//before: memset( PageStrg, 0, sizeof(&PageStrg) );
	memset( PageStrg, 0, sizeof(PageStrg) );
}

PageDesc* PageFind( void* ptr, char color )
{
     //Who'll check 'color' value, hm?
     if ( color < PG_COLOR_GREEN || color > PG_COLOR_RED)
	  return NULL;
     
	for( PageDesc* Pg = PageStrg[color]; Pg; Pg = Pg->next ) // Useless 'for' because of this little ';'
	       if( Pg->uKey == CALC_PAGE_KEY(ptr,color) )
		    return Pg;                                                                                                                                     
    return NULL;
}


//Почему ф-я имеет return value типа PageDesc*, если она ничего не возвращает?
PageDesc* PageReclaim( UINT cnt )
{
     //Вставить проверку значения cnt, чтобы оно было меньше или равно кол-ву страниц
     if (cnt > PagesAmountInDB(...))
     {
	  //желаемый результат - ошибка, изменeние cnt etc
     }
     
	UINT color = 0;
	PageDesc* Pg; //Возможно, стоит создавать указатель на начало списка страниц, а не пустой? 
	//В данном случае мы удаляем первую страницу нулевого цвета, а потом сразу же переходим к списку первого цвета 
	while( cnt )
	{
		Pg = Pg->next; //Seg fault
		PageRemove( PageStrg[ color ] );
		cnt--;
		if( Pg == NULL )
		{
			color++; //color легко выходит за границы 2 при больших значениях cnt
			Pg = PageStrg[ color ];
		}
	}
}
            
PageDesc* PageInit( void* ptr, UINT color )
{
     //Check color again
     if ( color < PG_COLOR_GREEN || color > PG_COLOR_RED)
	  return NULL;
     
    PageDesc* pg = new PageDesc;
    if( pg )
        do PAGE_INIT(pg, ptr, color) while(0); //Заменили &pg -> pg; добавили do ... while (0)
    else
        printf("Allocation has failed\n");
    return pg;
}

/**
 * Print all mapped pages
 */
void PageDump()
{
     //Неграмотно. Ноль заменим на PG_COLOR_GREEN 
	UINT color = PG_COLOR_GREEN;
	#define PG_COLOR_NAME(clr) #clr
	char* PgColorName[] = 
	{
		PG_COLOR_NAME(PG_COLOR_GREEN),
		PG_COLOR_NAME(PG_COLOR_YELLOW),
		PG_COLOR_NAME(PG_COLOR_RED)
	}; //before: wrong order?

	while( color <= PG_COLOR_RED ) // before: color <= PG_COLOR_RED, но теперь-то PG_COLOR_RED = 2, так что все ОК
	{
		//before: printf("PgStrg[(%s) %u] ********** \n", color, PgColorName[color] );
		printf ("PgStrg [(%u) %s] ********** \n", color, PgColorName[color]);
		for( PageDesc* Pg = PageStrg[color++]; Pg != NULL; Pg = Pg->next ) //before: PageStrg[++color] is not safe 'cause if color == 2 we'll have seg fault
		{
			if( Pg->uAddr == NULL ) //Было '='
				continue;
			//Не объявлена uAddr. Наверное, тут имеется в виду cAddr. Но я вообще не понимаю в чем смысл этого кода...

			printf("Pg :Key = 0x%x, addr %p\n", Pg->uKey, Pg->uAddr );
		}
	}
	#undef PG_COLOR_NAME
}
